/*
 * Analyzer.c
 * VB Script Analyzer
 * @author Gregoire JACOB (gregoire.jacob@orange-ftgroup.com)
 * @date 27/08/2008
 * @version 1.1
 * Central module, entry point of the analyzer
 */

#include ".\Includes\Analyzer.h"
#include <time.h>

/**
 * main()
 * Open the script and launch a syntactic analysis
 */
int __cdecl main( int argc, char ** argv ){
	int i, shortn; errno_t err;
	char shortname[NAME_MAX_LENGTH];
	char dbname[NAME_MAX_LENGTH];
	clock_t t1, t2, t3, t4; float t;
	FILE * pf_Script = NULL;
	FILE * pf_Logf = NULL;
	FILE * pf_Odbf = NULL;
	struct SCRIPT script;
	struct TYPING types;

	//Structures Initialization
	memset(&script,0,sizeof(struct SCRIPT));
	memset(&types,0,sizeof(struct TYPING));
	//Parameters checking
	if(argc != 4){
		printf("[-] Incorrect parameters, correct usage is:\n");
		printf("      VBScriptAnalyzer -t/b [Script file] [Log file]\n");
		printf("      -t/b text or binary output (binary is required for detection\n");
	}else{
		//Opening the script file
		strcpy_s(shortname,NAME_MAX_LENGTH,argv[2]);
		for(i=0,shortn=0;i<strlen(shortname);i++){
			if(shortname[i]=='\\') shortn=i+1;
		}
		strcat_s(script.name,NAME_MAX_LENGTH,&shortname[shortn]);
		strcpy_s(scriptname,NAME_MAX_LENGTH,&shortname[shortn]);
		err = fopen_s(&pf_Script, argv[2],"rb");
		if(err){
			printf("[-] Script file can not be opened\n");
			exit(0);
		}//if

		//Opening the log file
		err = fopen_s(&pf_Logf,argv[3],"wb");
		if(err){
			printf("[-] Log file can not be created\n");
			exit(0);
		}//if

		//Checking running mode
		if(argv[1][1]=='t'){
			printf("[+] Running in textual mode\n");
			textual = 1; //Textual mode
		}else{
			printf("[+] Running in binary mode\n");
			textual = 0; //Binary mode
		}

		//Beginning static syntactic analysis
		t1 = clock();
		printf("[+] Beginning syntactic analysis in static mode\n");
		localizeFuncAndProc(&script,&types,pf_Script);
		analyzeMain(&script,&types,pf_Script);
		for(i=0;i<script.nbfunc;i++){
			if(script.strciphered&&i==script.cipherfunction) continue;
			parseFunction(i,&script,&types,pf_Script);
		}
		for(i=0;i<script.nbproc;i++){
			parseProcedure(i,&script,&types,pf_Script);
		}
		t2 = clock();
		if(textual) printfScript(pf_Logf,&script);

		//Beginning analysis following execution path
		t3 = clock();
		isMissing = 0;
		printf("[+] Beginning dynamic analysis exploring execution paths\n");
		startMain(pf_Logf,&script,&types);
		t4 = clock();

		//Storing object database
		if(textual){
			printfTyping(pf_Logf,&types);
			t = (t2-t1)+(t4-t3);
			fprintf(pf_Logf,"\n\n[+] Execution time: %f sec (%f ticks)\n",t/CLOCKS_PER_SEC,t);
			fprintf(pf_Logf,"[+] t1:%d t2:%d t3:%d t4:%d\n",t1,t2,t3,t4);
		}else{
			int lgth = (int)strlen(argv[3]);
			strcpy_s(dbname,NAME_MAX_LENGTH,argv[3]);
			for(i=lgth-4;i<lgth;i++){
				if(dbname[i]=='.'){dbname[i]=0; break;}
			}
			strcat_s(dbname,NAME_MAX_LENGTH,".odb");
			err = fopen_s(&pf_Odbf,dbname,"wb");
			if(err){
				printf("[-] Object database file can not be opened\n");
			}else{
				printf("[+] Storing object database in %s\n",dbname);
				storeTyping(pf_Odbf,&types);
			}
		}//if
		
		fclose(pf_Script);
    }//if

	return 0;
}
